A component included in all computing devices is memory. A device's main memory (e.g., RAM, flash, etc.) provides storage that can be quickly written to and read from by a processor. Main memory is allocated to an operating system and programs during runtime (throughout the duration of execution). When a program terminates, memory allocated to that program is freed (deallocated), and may subsequently be allocated to a different program.
Frequently, data that is stored in main memory does not change once it has been written. For example, when process code of a program or operating system is loaded into memory (thus initiating a process), much of the process code includes instructions and data structures that will not change for the life of the process.
Often, multiple instances of the same program (application) are run concurrently. When multiple instances of a program are run concurrently, it is preferable to share as much physical memory between the multiple instances as possible. This may be accomplished by having virtual memory space of each instance map to the same blocks of physical memory (e.g., physical memory pages).
There are two conventional methods of sharing physical memory between multiple instances of a program. In a first conventional method, an operating system can require that processes identify which blocks of memory are likely to change, and which blocks of memory are never going to change. An operating system may then allow the blocks of memory that will never change to be shared between different instances of a program.
In a second conventional method, the operating system can allocate all data to memory designated as read only memory (whether the data is expected to change or not). All memory is initially shared between multiple instances of a program. When a process attempts to write to the memory, a copy of the page that is being written to is generated. This copy of the original memory page is placed into the virtual memory space of the process (application instance) that attempted to write to the memory page to replace the original memory page. For example, two instances of the same application may each initially share 65 memory pages. If the first instance of the application attempts to write to memory page 55 (e.g., to update data), to ensure that the change affects only the first instance of the process, the operating system copies the contents of page 55 into a free physical memory page. The operating system then changes a mapping of the first instance of the application so that the virtual memory space now maps page 55 to the freshly allocated physical memory page. The first instance may then successfully write to the freshly allocated memory page. After this series of events, the two instances may share memory pages 1-54 and 56-65, and each may now have a different memory page 55 that is not shared. Therefore a total of 66 memory pages may subsequently be used.
Frequently, when a process is started up, it writes to a collection of data structures that were just loaded into memory as it initializes itself. It is likely that different instances of a program will write significant portions of the same data. Therefore, multiple instances will end up having their own copy of the same data stored in different physical memory pages. This may consume unnecessary amounts of memory.